package com.alangyun.remind.service.impl;

import java.util.*;

import com.alangyun.remind.repository.data.*;
import org.springframework.stereotype.Service;

import com.alangyun.remind.BaseActor;
import com.alangyun.remind.error.MindException;
import com.alangyun.remind.repository.StoreEngine;
import com.alangyun.remind.repository.algorithm.AlgorithmHelper;
import com.alangyun.remind.repository.cache.EmployeeCache;
import com.alangyun.remind.service.IEmployeeService;
import com.alangyun.remind.utils.Utility;
import com.alangyun.remind.vo.FilterParam;
import com.alangyun.remind.vo.leader.LeaderSum;
import com.alangyun.remind.vo.user.JobView;
import com.alangyun.remind.vo.user.SixDimenUser;
import com.alangyun.remind.vo.user.SpecialView;
import com.alangyun.remind.vo.user.UserView;

@Service
public class EmployeeService extends BaseActor implements IEmployeeService {

	private void validateDataset() {
			if (!EmployeeCache.my().isLoaded()) {
				try {
				EmployeeDataset data = StoreEngine.openDataset(EmployeeDataset.class,
						new Class<?>[] { EmployeeCaution.class, SixValue.class, NameTerm.class });
				EmployeeCache.my().addDataset(data);
				} catch (Exception ex) {
					throw new MindException("加载专业技能预警数据失败，请确认是否已上传预警数据", ex);
				}
			}

	}
	
	@Override
	public FilterParam categroies() {

		validateDataset();
		
		EmployeeDataset db= EmployeeCache.my().get();
		
		FilterParam ret = new FilterParam();
		ret.setJobs(db.getJobs());
		ret.setProfs(db.getProfs());
		ret.setTeams(db.getTeams());
		
		return ret;
	}
	
	private void calcMaxMin(UserView uv, EmployeeDataset dataset, boolean isSpecial) {
		EmployeeCaution user = isSpecial ? dataset.getSpecialUser(): dataset.getStandardUser();
		
		SixValue max = new SixValue();
		SixValue min = new SixValue();
		
		max.setC(user.getC());
		max.setP(user.getP());
		max.setS(user.getS());
		max.setW(user.getW());
		max.setX(user.getX());
		max.setZ(user.getZ());
		max.setSinValue(user.getSinValue());

		min.setC(user.getC() / 2);
		min.setP(user.getP() / 2);
		min.setS(user.getS() / 2);
		min.setW(user.getW() / 2);
		min.setX(user.getX() / 2);
		min.setZ(user.getZ() / 2);
		min.setSinValue(user.getSinValue());
		
		uv.setStandard(max);
		uv.setMin(min);
	}

	@Override
	public UserView listEmployee(boolean isSpecial, Integer[] depart, Integer[] profs, Integer[] jobs) {

		validateDataset();

		EmployeeDataset data = EmployeeCache.my().get();
		if (data == null)
			return null;

		UserView ret = new UserView();
		calcMaxMin(ret, data, isSpecial);
		ret.setUsers(new ArrayList<>());

		// 处理人员并统计
		if (data.getDatas() != null && data.getDatas().size() > 0) {
			boolean isget= false;
			double referValue= 0.0;
			int cc=1;
			for (EmployeeCaution caution : data.getDatas()) {
				if (Utility.inArray(depart, caution.getDepart()) && Utility.inArray(profs, caution.getTechLevel())
						&& Utility.inArray(jobs, caution.getJob01())) {
					if(!isget) {
						referValue = caution.getSuit();
						isget=true;
					}

					SixDimenUser user = new SixDimenUser();
					user.setNo(caution.getId());
					user.setName(caution.getName());
					user.setW(caution.getW());
					user.setC(caution.getC());
					user.setP(caution.getP());
					user.setX(caution.getX());
					user.setS(caution.getS());
					user.setZ(caution.getZ());
					user.setSuit(caution.getSuit());
					user.setDiff(Math.abs(caution.getSuit()-referValue));
					
					user.setJob(EmployeeCache.my().getTeamName(caution.getJob01()));
					user.setAge(caution.getAge());
					user.setPlast(4.0);
					user.setSpec(7.0);
					user.setConform(95.0);
					user.setRecomend((cc++)+"");
					if(cc==data.getDatas().size())
						user.setRecomend("不推荐");
					

					ret.getUsers().add(user);
				}
			}
		}

		return ret;
	}


	String[] specNames = new String[] {
			"带电作业",
			"停送电",
			"三种人：工作许可人",
			"三种人：工作负责人",
			"三种人：工作票签发人"
	};
	@Override
	public SpecialView listSpecialUser(Integer[] depart, Integer[] profs, Integer[] jobs) {

		validateDataset();

		EmployeeDataset data = EmployeeCache.my().get();
		if (data == null)
			return null;

		SpecialView ret = SpecialView.create();

		Map<String, SpecialView.SpecialSum> map= new HashMap<>();
		// 处理人员并统计
		if (data.getDatas() != null && data.getDatas().size() > 0) {
			for (EmployeeCaution caution : data.getDatas()) {
				if (Utility.inArray(depart, caution.getDepart()) && Utility.inArray(profs, caution.getTechLevel())
						&& Utility.inArray(jobs, caution.getJob01()) && caution.getSftsgw()) {
										
					String lbmc = caution.getTsgwlb();
					if(lbmc==null||lbmc.length()==0)
						continue;
					
					SpecialView.SpecialSum sum= map.get(lbmc);
					if(sum==null) {
						sum = new SpecialView.SpecialSum();
						sum.setName(lbmc);
						map.put(lbmc, sum);
					}
					sum.incTotal();

					SpecialView.SpecialUser user = new SpecialView.SpecialUser();
					user.setId(caution.getId());
					user.setName(caution.getName());
					user.setUnit(caution.getUnitName());
					user.setDepart(caution.getDepartName());
					user.setGroup(caution.getGroupName());
					user.setCert(caution.getTsgwzs());

					if(caution.getSfcz()) {
						sum.intOwn();
					ret.getOwners().add(user);
					}else
						ret.getUnowners().add(user);
				}
			}
		}
		
		Collection<SpecialView.SpecialSum> values= map.values();
		for(String name: specNames) {
			for(SpecialView.SpecialSum sum: values) {
				if(name.indexOf(sum.getName())>=0) {
					sum.setName(name);
					ret.getSums().add(sum);
					break;
				}
			}
		}
		

		return ret;
	}

	private static String[] SumTypes = new String[] {  
			"5年及以上" ,
			"4年", 
			"3年", 
			"2年", 
			"1年"
	};
	private static int normalCycle = 6;//轮岗年限
	
	@Override
	public JobView listJobUser(Integer[] depart, Integer[] profs, Integer[] jobs) {

		validateDataset();

		EmployeeDataset data = EmployeeCache.my().get();
		if (data == null)
			return null;

		JobView ret = JobView.create();

		// 处理人员并统计
		if (data.getDatas() != null && data.getDatas().size() > 0) {
			int[] counts = new int[SumTypes.length];
			Arrays.fill(counts, 0);
			int total =0;
			for (EmployeeCaution caution : data.getDatas()) {
				if (Utility.inArray(depart, caution.getDepart()) && Utility.inArray(profs, caution.getTechLevel())
						&& Utility.inArray(jobs, caution.getJob01())) {
					//如果距离轮岗时间和上岗时间都没给定值，则无法计算，继续找下一个
					if(caution.getJllgsj()<=0&&caution.getSgsj()==null)
						continue;
					
					//轮岗年限
					int lgnx = caution.getLgnx()!=null&&caution.getLgnx()>0?caution.getLgnx():normalCycle;
					int jllgsc =0;//距离轮岗时长
					int sgsc = 0; //上岗时长
					if(caution.getSgsj()!=null) {
						sgsc = Utility.ageLimit(caution.getSgsj());
						jllgsc = lgnx - sgsc;
					}else {
						jllgsc = caution.getJllgsj().intValue();
						sgsc = lgnx - jllgsc;
					}
					int thannx = lgnx - sgsc;
					if (thannx <= -4)
						counts[0]++;
					else if (thannx <=-3)
						counts[1]++;
					else if (thannx <=-2)
						counts[2]++;
					else if (thannx <=-1)
						counts[3]++;
					else if (thannx <= 0)
						counts[4]++;
					total ++;					

					JobView.JobUser user = new JobView.JobUser();
					user.setId(caution.getId());
					user.setName(caution.getName());
					user.setAge(caution.getAge());
					user.setUnit(caution.getUnitName());
					user.setDepart(caution.getDepartName());
					user.setGroup(caution.getGroupName());
					user.setJob(caution.getXrgw());
					user.setCareer(caution.getTechMeu());
					user.setOtherJob(caution.getHggw());
					user.setJobDate(caution.getSgsj()==null?"":Utility.dateToStr(caution.getSgsj(),"yyyy-MM-dd"));
					user.setRemainYears(jllgsc+"");
					user.setYearLimit(lgnx+"");
					user.setYears(sgsc+"");

					ret.getUsers().add(user);
				}
			}
			for (int index = 0; index < SumTypes.length; index++) {
				JobView.LimitSum sum = new JobView.LimitSum();
				sum.setName(SumTypes[index]);
				sum.setUnfair(counts[index]);
				sum.setFair(total-sum.getFair());
				ret.getSums().add(sum);
			}
		}		

		return ret;
	}
	
	@Override
	public EmployeeCaution updateSpecialUser(EmployeeCaution caution) {
		validateDataset();

		EmployeeDataset data = EmployeeCache.my().get();
		if (data == null)
			throw new MindException("获取预警数据失败，请确认是否已经上传资料");


		try {
			AlgorithmHelper.calcXOfUser(caution);
			data.setSpecialUser(caution);
			StoreEngine.saveDataset(data, "更新特定人岗适配模型");

		} catch (Exception e) {
			throw new MindException("生成特殊岗位模型失败:" + e.getMessage(), e);
		}

		return caution;
	}

	@Override
	public EmployeeCaution updateStandardUser(List<Integer> team, List<Integer> job) {
        validateDataset();

        EmployeeDataset data = EmployeeCache.my().get();
        if (data == null)
            throw new MindException("获取预警数据失败，请确认是否已经上传资料");

        EmployeeCaution standardCaution;
        try {
            standardCaution = AlgorithmHelper.getStandardCaution(team, job, data);
            data.setStandardUser(standardCaution);
			StoreEngine.saveDataset(data, "更新通用人岗适配模型");

        } catch (Exception e) {
            throw new MindException("生成通用岗位模型失败:" + e.getMessage(), e);
        }

        return standardCaution;
    }

	@Override
	public EmployeeCaution findSpecialUser() {
		validateDataset();

		EmployeeDataset data = EmployeeCache.my().get();
		if (data == null)
			throw new MindException("获取预警数据失败，请确认是否已经上传资料");
		
		return data.getSpecialUser();
	}
	
	@Override
	public EmployeeCaution findStandardUser() {
		validateDataset();

		EmployeeDataset data = EmployeeCache.my().get();
		if (data == null)
			throw new MindException("获取预警数据失败，请确认是否已经上传资料");
		
		return data.getStandardUser();
	}

}
